﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Cherry.Agile.RpcService
{
    /// <summary>
    /// 服务扩展处理器，ServiceExtentProcessor此实现是IServiceExtentProcessor基础实现，用于支持总体调度执行多个扩展接口。
    /// </summary>
    public class ServiceExtentProcessor : IServiceExtentProcessor
    {
        /// <summary>
        /// 多线程锁
        /// </summary>
        public static object _syncLock = new object();

        /// <summary>
        /// 服务扩展列表
        /// </summary>
        private Dictionary<string, IServiceExtentProcessor> _serviceExtentList;

        public T GetExtentor<T>() where T : IServiceExtentProcessor
        {
            string name = typeof(T).Name;
            if (_serviceExtentList != null && _serviceExtentList.ContainsKey(name))
                return (T)_serviceExtentList[name];
            else
                return default(T);
        }

        /// <summary>
        /// 添加一个扩展实例
        /// </summary>
        /// <param name="extenProcessor">扩展插件</param>
        public void Add(IServiceExtentProcessor extenProcessor)
        {
            lock (_syncLock)
            {
                if (_serviceExtentList == null)
                    _serviceExtentList = new Dictionary<string, IServiceExtentProcessor>();
                string name = extenProcessor.GetType().Name;
                if (name == typeof(ServiceExtentProcessor).Name) //自身实例不能加列表
                    return;
                _serviceExtentList.Add(name, extenProcessor);
            }
        }

        /// <summary>
        /// 移除一个扩展插件
        /// </summary>
        /// <param name="name">插件的类名</param>
        public void Remove(string name)
        {
            lock (_syncLock)
            {
                if (_serviceExtentList != null && _serviceExtentList.ContainsKey(name))
                    _serviceExtentList.Remove(name);
            }
        }

        /// <summary>
        /// 重置，停止所有扩展插件
        /// </summary>
        public void Reset()
        {
            lock (_syncLock)
            {
                if (_serviceExtentList != null)
                {
                    _serviceExtentList.Clear();
                    _serviceExtentList = null;
                }
            }
        }

        /// <summary>
        /// 开始处理
        /// </summary>
        /// <param name="context"></param>
        public void ProcessOnStarting(ProcessContext context)
        {
            if (_serviceExtentList != null)
            {
                try
                {
                    foreach (IServiceExtentProcessor processor in _serviceExtentList.Values)
                        processor.ProcessOnStarting(context);
                }
                catch (Exception ex)
                {
                    ErrorHandle(ex, context);
                }
            }
        }

        /// <summary>
        /// 结束处理
        /// </summary>
        /// <param name="context"></param>
        public void ProcessOnEnding(ProcessContext context)
        {
            if (_serviceExtentList != null)
            {
                try
                {
                    foreach (IServiceExtentProcessor processor in _serviceExtentList.Values)
                        processor.ProcessOnEnding(context);
                }
                catch (Exception ex)
                {
                    ErrorHandle(ex, context);
                }
            }
        }

        /// <summary>
        /// 跟踪异常信息
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <param name="context"></param>
        public void ProcessTrace(Exception ex, ProcessContext context)
        {
            if (_serviceExtentList != null)
            {
                try
                {
                    foreach (IServiceExtentProcessor processor in _serviceExtentList.Values)
                        processor.ProcessTrace(ex, context);
                }
                catch (Exception ex2)
                {
                    ErrorHandle(ex2, context);
                }
            }
        }

        /// <summary>
        /// 跟踪信息输出
        /// </summary>
        /// <param name="traceMessage">The trace message.</param>
        /// <param name="context">The context.</param>
        public void ProcessTrace(string traceMessage, ProcessContext context)
        {
            if (_serviceExtentList != null)
            {
                try
                {
                    foreach (IServiceExtentProcessor processor in _serviceExtentList.Values)
                        processor.ProcessTrace(traceMessage, context);
                }
                catch (Exception ex)
                {
                    ErrorHandle(ex, context);
                }
            }
        }

        private void ErrorHandle(Exception ex, ProcessContext context)
        {
            context.WriteTrace(string.Format("Error occur in ServiceExtentProcessor:{0}-{1}", ex.Message, ex.StackTrace));
        }
    }
}
